<?php

/**
 * @author Jose Luis Quintana <joseluis@lbn.pe>
 * @property JLAjax $_instance
 * @property string $_request_id_name
 */
class JLAjax {

    private static $_instance = null;
    private static $_request_id_name = 'HTTP_X_CSRF_TOKEN';

    /**
     * JLAjax::getInstance()
     * Get a single instance of the class. 
     * @return JLAjax
     */
    public static function getInstance() {
        if (!isset(self::$_instance)) {
            self::$_instance = new self();
        }

        return self::$_instance;
    }

    public function checkToken() {
        if (!$this->existsToken() || ($this->isAjaxRequest() && !$this->isValidToken())) {
            $this->resetToken();
        }
    }

    public function resetToken() {
        $this->setToken(self::getNewToken());
    }

    public static function getNewToken() {
        return str_rot13(base64_encode(hash('sha1', time() * rand(-683, 787))));
    }

    public function setToken($token) {
        $_SESSION[self::$_request_id_name] = $token;
    }

    public function getToken() {
        return $_SESSION[self::$_request_id_name];
    }

    public function existsToken() {
        return isset($_SESSION[self::$_request_id_name]) && !is_null($this->getToken());
    }

    public function isValidToken() {
        $id = $this->getRequestToken();
        return (!empty($id) && ($id === $this->getToken()));
    }

    public function getRequestToken() {
        return $_SERVER[self::$_request_id_name];
    }

    public function response($response_code, $data = NULL) {
        $json = json_encode(array(
            'header' => array(
                'code' => $response_code, 'session' => session_id(),
                'token' => $this->getToken()
            ), 'response' => $data));

        self::jsonHeader($json);
        exit;
    }

    public function jsonHeader($data = '') {
        header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); 
        header("Last-Modified: " . gmdate( "D, d M Y H:i:s" ) . "GMT"); 
        header("Cache-Control: no-cache, must-revalidate"); 
        header("Pragma: no-cache");
        header("Content-type: application/json");
        ob_start('ob_gzhandler');
        echo $data;
        ob_end_flush();
    }
    
    public function jsHeader($data = '') {
        header('Content-type: text/javascript');
        header('Expires: Fri, 01 Jan 2010 05:00:00 GMT');

        if (strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE') == FALSE) {
            header('Cache-Control: no-cache');
            header('Pragma: no-cache');
        }

        ob_start('ob_gzhandler');
        echo $data;
        ob_end_flush();
    }

    /**
     * JLAjax::isAjaxRequest()
     * Check if is ajax request.
     * @return bool
     */
    public function isAjaxRequest() {
        return !!(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest');
    }

    public function forbiddenHeader() {
        header('HTTP/1.1 403 Forbidden');
        echo 'The server has refused to fulfill the request.';
        exit();
    }

}